﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DevExpress.Utils;
using DevExpress.XtraEditors;
using FileManager_Client.BusinessLogic;
using FileManager_Client.BusinessLogic.FileManagerUserService;
using FileManager_Client.Utility;

namespace FileManager_Client.PresentationLayer.NewUi
{
    public partial class AddEmployeeForm : BaseForm
    {
        #region Form Constructor
        private LoadingWaitForm _loadingWaitForm;
        private UserService _userService;
        private List<CompanyResult> _companyResults;
        private List<CompanyGroupResult> _companyGroupResults;
        private List<UserGroupResult> _userGroupResults;
        public List<UserResult> ChooseUser { get; set; }
        private static readonly object lockWait = new object();
     
        public AddEmployeeForm()
        {
            InitializeComponent();
            Ttc_Message.ShowShadow = true;
            Ttc_Message.Rounded = true;
            Ttc_Message.ShowBeak = true;
            Ttc_Message.SetToolTipIconType(tb_SearchPeopleName, ToolTipIconType.Information);
            _userService = new UserService();
            lv_AddEmployee.Items.Clear();
            lv_SearchResult.Items.Clear();
            ChooseUser = new List<UserResult>();
            tb_SearchPeopleName.TextChanged += tb_SearchPeopleName_TextChanged;
            tb_SearchPeopleName.KeyPress += tb_SearchPeopleName_KeyPress;
        }
        #endregion

        #region Txtbox Search People Event
        void tb_SearchPeopleName_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar != 13) return;
            SearchUserByName();
        }

        void tb_SearchPeopleName_TextChanged(object sender, EventArgs e)
        {
            Ttc_Message.HideHint();
        }
        #endregion

        #region Search People Method
        private void SearchUserByName()
        {
            try
            {
                Ttc_Message.HideHint();
                if (string.IsNullOrEmpty(tb_SearchPeopleName.Text.Trim()))
                {
                    ShowTipMessage("关键字不能为空!");
                    return;
                }
                lock (lockWait)
                {
                    _loadingWaitForm = new LoadingWaitForm();
                    _loadingWaitForm.SetCaption(GlobalString.System_Config_String.MbxInfoStr);
                    _loadingWaitForm.SetDescription(GlobalString.System_Config_String.SearchUserStr);
                    _loadingWaitForm.StartPosition = FormStartPosition.CenterScreen;
                }
                var backgroundWorker = new BackgroundWorker();
                backgroundWorker.DoWork += backgroundWorker_DoWork;
                var searchKey = new SearchUserNameArgs
                {
                    NameKeyk__BackingField = tb_SearchPeopleName.Text
                };
                backgroundWorker.RunWorkerAsync(searchKey);
                _loadingWaitForm.ShowDialog();
            }
            catch (Exception ex)
            {
                LogLoader.Instance.Log.Error("btn_SearchPeople_Click has problem", ex);
                XtraMessageBox.Show("搜索用户失败，请联系管理员!", GlobalString.System_Exception_String.MbxErrorStr, MessageBoxButtons.OK,
                                    MessageBoxIcon.Error);
            }
        }

        void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            var result = _userService.SearchUserByName(e.Argument as SearchUserNameArgs);
            Invoke((EventHandler)delegate
            {
                _loadingWaitForm.Close();
                lv_SearchResult.Items.Clear();
                foreach (var userResult in result.Resultk__BackingField)
                {
                    var listViewItem = new ListViewItem
                    {
                        Text = userResult.UserNamek__BackingField,
                        ImageKey = "people",
                        Tag = userResult
                    };
                    var subListViewItem = new ListViewItem.ListViewSubItem { Text = userResult.CompanyNamek__BackingField };
                    listViewItem.SubItems.Add(subListViewItem);
                    lv_SearchResult.Items.Add(listViewItem);
                }
            });
        }

        private void ShowTipMessage(string message)
        {
            Ttc_Message.ShowHint(message, tb_SearchPeopleName, ToolTipLocation.BottomCenter);
        }
        #endregion

        #region Button Confirm Event
        private void btn_Confrim_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem item in lv_AddEmployee.Items)
            {
                ChooseUser.Add(item.Tag as UserResult);
            }
            Close();
        }
        #endregion

        #region Button Add One People Add All People Delete One People Delete All People
        private void btn_AddEmployee_Click(object sender, EventArgs e)
        {
            if (lv_SearchResult.Items.Count <= 0) return;
            foreach (var listViewItem
                in from ListViewItem temp in lv_SearchResult.SelectedItems
                   select temp.Tag as UserResult into user
                   where lv_AddEmployee.Items.Find(user.UserIdk__BackingField, true).Length <= 0
                   select new ListViewItem
                   {
                       Text = user.UserNamek__BackingField,
                       ImageKey = "people",
                       Tag = user,
                       Name = user.UserIdk__BackingField
                   })
            {
                lv_AddEmployee.Items.Add(listViewItem);
            }
        }

        private void btn_AddAllEmployee_Click(object sender, EventArgs e)
        {
            if (lv_SearchResult.Items.Count <= 0) return;
            foreach (var listViewItem
            in from ListViewItem temp in lv_SearchResult.Items
               select temp.Tag as UserResult into user
               where lv_AddEmployee.Items.Find(user.UserIdk__BackingField, true).Length <= 0
               select new ListViewItem
               {
                   Text = user.UserNamek__BackingField,
                   ImageKey = "people",
                   Tag = user,
                   Name = user.UserIdk__BackingField
               })
            {
                lv_AddEmployee.Items.Add(listViewItem);
            }
        }

        private void btn_DeleteEmployee_Click(object sender, EventArgs e)
        {
            if (lv_AddEmployee.SelectedItems.Count <= 0) return;
            foreach (ListViewItem temp in lv_AddEmployee.SelectedItems)
            {
                lv_AddEmployee.Items.Remove(temp);
            }
        }

        private void btn_DeleteAllEmployee_Click(object sender, EventArgs e)
        {
            lv_AddEmployee.Items.Clear();
        }

        #endregion

        #region Table Control Event
        private void tc_Collection_SelectedIndexChanged(object sender, EventArgs e)
        {
            Ttc_Message.HideHint();
            lv_SearchResult.Items.Clear();
            tc_Collection.SelectedTab.Controls.Add(pl_MoveControl); 
            lv_SearchResult.Update();
            lv_AddEmployee.Update();
        }
        #endregion

        #region Button Search People Event
        private void btn_SearchPeople_Click(object sender, EventArgs e)
        {
            SearchUserByName();
        }
        #endregion

        #region Check Cache And Set Cache Data Method
        private void SetCacheData()
        {
            try
            {
                lock (lockWait)
                {
                    _loadingWaitForm = new LoadingWaitForm();
                    _loadingWaitForm.SetCaption(GlobalString.System_Config_String.MbxInfoStr);
                    _loadingWaitForm.SetDescription(GlobalString.System_Config_String.GetCompanyGroupAndUserGroup);
                    _loadingWaitForm.StartPosition = FormStartPosition.CenterScreen;
                }
                var backgroundWorkerGetCompanyInfo = new BackgroundWorker();
                backgroundWorkerGetCompanyInfo.DoWork += backgroundWorkerGetCompanyInfo_DoWork;
                backgroundWorkerGetCompanyInfo.RunWorkerAsync();
                _loadingWaitForm.ShowDialog();
            }
            catch (Exception ex)
            {
                LogLoader.Instance.Log.Error("SetCacheData has problem", ex);
                XtraMessageBox.Show("获取组织机构失败，请联系管理员!", GlobalString.System_Exception_String.MbxErrorStr, MessageBoxButtons.OK,
                                    MessageBoxIcon.Error);
            }
        }

        void backgroundWorkerGetCompanyInfo_DoWork(object sender, DoWorkEventArgs e)
        {
            var result = _userService.GetCompanyGroupAndUserGroup();
            CacheGlobal.Add(GlobalString.System_Config_String.AllCompanyCollectionCache, result.CompanyResultsk__BackingField.ToList());
            CacheGlobal.Add(GlobalString.System_Config_String.CompanyGroupCollectionCache, result.CompanyGroupResultsk__BackingField.ToList());
            CacheGlobal.Add(GlobalString.System_Config_String.UserGroupCollectionCache, result.UserGroupResultsk__BackingField.ToList());
            if (!IsHandleCreated)
                CreateHandle();
            Invoke((EventHandler)delegate
            {
                _loadingWaitForm.Close();
            });
        }
        #endregion

        #region Form Event
        private void AddEmployeeForm_Shown(object sender, EventArgs e)
        {
            _companyResults =
  CacheGlobal.GetCache(GlobalString.System_Config_String.AllCompanyCollectionCache) as List<CompanyResult>;
            _companyGroupResults =
                CacheGlobal.GetCache(GlobalString.System_Config_String.CompanyGroupCollectionCache) as List<CompanyGroupResult>;
            _userGroupResults =
                CacheGlobal.GetCache(GlobalString.System_Config_String.UserGroupCollectionCache) as List<UserGroupResult>;
            if (null == _companyResults || null == _companyGroupResults || null == _userGroupResults)
                SetCacheData();
            _companyResults =
CacheGlobal.GetCache(GlobalString.System_Config_String.AllCompanyCollectionCache) as List<CompanyResult>;
            _companyGroupResults =
                CacheGlobal.GetCache(GlobalString.System_Config_String.CompanyGroupCollectionCache) as List<CompanyGroupResult>;
            _userGroupResults =
                CacheGlobal.GetCache(GlobalString.System_Config_String.UserGroupCollectionCache) as List<UserGroupResult>;
            #region 组织结构公共组

            var companyGroupRoot = _companyGroupResults.Where(x => x.Pidk__BackingField == 0).ToList();
            foreach (var companyGroupResult in companyGroupRoot)
            {
                var rootNode = new TreeNode
                {
                    Text = companyGroupResult.Namek__BackingField,
                    Tag = companyGroupResult
                };
                var subItemCollection = FindCompanyGroupSubItem(companyGroupResult.GroupIdk__BackingField);
                foreach (var treeNode in subItemCollection)
                    rootNode.Nodes.Add(treeNode);
                tv_CompanGroup.Nodes.Add(rootNode);
            }
            var userGroupRoot = _userGroupResults.Where(x => x.Pidk__BackingField == 0);
            foreach (var userGroupResult in userGroupRoot)
            {
                var rootNode = new TreeNode
                {
                    Text = userGroupResult.Namek__BackingField,
                    Tag = userGroupResult
                };
                var subItemCollection = FindUserGroupSubItem(userGroupResult.Idk__BackingField);
                foreach (var treeNode in subItemCollection)
                    rootNode.Nodes.Add(treeNode);
                tv_EmployeeGroup.Nodes.Add(rootNode);
            }
            var companyRoot = _companyResults.Where(x => string.IsNullOrEmpty(x.Pidk__BackingField));
            foreach (var companyResult in companyRoot)
            {
                var rootNode = new TreeNode
                {
                    Text = companyResult.ShortNamek__BackingField,
                    Tag = companyResult
                };
                var subItemCollection = FindGroupSubItem(companyResult.Idk__BackingField);
                foreach (var treeNode in subItemCollection)
                    rootNode.Nodes.Add(treeNode);
                tv_Company.Nodes.Add(rootNode);
            }

            #endregion
        }
        #endregion

        #region while company group and user group data
        private IEnumerable<TreeNode> FindCompanyGroupSubItem(int groupId)
        {
            var result = new List<TreeNode>();
            var subCompanyGroup = _companyGroupResults.Where(x => x.Pidk__BackingField == groupId);
            foreach (var companyGroupResult in subCompanyGroup)
            {
                var subItem = new TreeNode
                {
                    Text = companyGroupResult.Namek__BackingField,
                    Tag = companyGroupResult
                };
                var subSubItemCollection = FindCompanyGroupSubItem(companyGroupResult.GroupIdk__BackingField);
                foreach (var treeNode in subSubItemCollection)
                    subItem.Nodes.Add(treeNode);
                result.Add(subItem);
            }
            return result;
        }

        private IEnumerable<TreeNode> FindUserGroupSubItem(int groupId)
        {
            var result = new List<TreeNode>();
            var subUserGroup = _userGroupResults.Where(x => x.Pidk__BackingField == groupId);
            foreach (var userGroupResult in subUserGroup)
            {
                var subItem = new TreeNode
                {
                    Text = userGroupResult.Namek__BackingField,
                    Tag = userGroupResult
                };
                var subSubItemCollection = FindUserGroupSubItem(userGroupResult.Idk__BackingField);
                foreach (var treeNode in subSubItemCollection)
                    subItem.Nodes.Add(treeNode);
                result.Add(subItem);
            }
            return result;
        }

        private IEnumerable<TreeNode> FindGroupSubItem(string sid)
        {
            var result = new List<TreeNode>();
            var subCompany = _companyResults.Where(x => x.Pidk__BackingField.Equals(sid));
            foreach (var companyResult in subCompany)
            {
                var subItem = new TreeNode
                {
                    Text = companyResult.ShortNamek__BackingField,
                    Tag = companyResult
                };
                var subSubItemCollection = FindGroupSubItem(companyResult.Idk__BackingField);
                foreach (var treeNode in subSubItemCollection)
                    subItem.Nodes.Add(treeNode);
                result.Add(subItem);
            }
            return result;
        }
        #endregion

        #region TreeView CompanyGroup Event
        private void tv_CompanGroup_AfterSelect(object sender, TreeViewEventArgs e)
        {
            var args = new SearchUserByCompanyCodeArgs
            {
                SearchUserByCompanyEnumk__BackingField = SearchUserByCompanyEnum.CompanyGroup
            };
            if (e.Node.Nodes.Count > 0)
            {
                var objectCollection = (from TreeNode temp in e.Node.Nodes from o in ReturnTreeNodeList(temp) select o).ToList();
                args.CodeCollectionk__BackingField = objectCollection.OfType<CompanyGroupResult>().Select(obj => obj.GroupIdk__BackingField.ToString()).ToArray();
            }
            else
            {
                var obj = e.Node.Tag as CompanyGroupResult;
                args.CodeCollectionk__BackingField = (new List<string> { obj.GroupIdk__BackingField.ToString() }).ToArray();
            }
            SearchUserByCompanCode(args);
        }
        #endregion

        #region TreeView EmployeeGroup Event
        private void tv_EmployeeGroup_AfterSelect(object sender, TreeViewEventArgs e)
        {
            var args = new SearchUserByCompanyCodeArgs
            {
                SearchUserByCompanyEnumk__BackingField = SearchUserByCompanyEnum.UserGroup
            };
            if (e.Node.Nodes.Count > 0)
            {
                var objectCollection = (from TreeNode temp in e.Node.Nodes from o in ReturnTreeNodeList(temp) select o).ToList();
                args.CodeCollectionk__BackingField = objectCollection.OfType<UserGroupResult>().Select(obj => obj.Idk__BackingField.ToString()).ToArray();
            }
            else
            {
                var obj = e.Node.Tag as UserGroupResult;
                args.CodeCollectionk__BackingField = (new List<string> { obj.Idk__BackingField.ToString() }).ToArray();
            }
            SearchUserByCompanCode(args);
        }
        #endregion

        #region TreeView Company Event
        private void tv_Company_AfterSelect(object sender, TreeViewEventArgs e)
        {
            var args = new SearchUserByCompanyCodeArgs
            {
                SearchUserByCompanyEnumk__BackingField = SearchUserByCompanyEnum.Company
            };
            if (e.Node.Nodes.Count > 0)
            {
                var objectCollection = (from TreeNode temp in e.Node.Nodes from o in ReturnTreeNodeList(temp) select o).ToList();
                args.CodeCollectionk__BackingField = objectCollection.OfType<CompanyResult>().Select(obj => obj.Idk__BackingField).ToArray();
            }
            else
            {
                var obj = e.Node.Tag as CompanyResult;
                args.CodeCollectionk__BackingField = (new List<string> { obj.Idk__BackingField }).ToArray();
            }
            SearchUserByCompanCode(args);
        }
        #endregion

        #region Search Company CompanyGroup UserGroup User
        private void SearchUserByCompanCode(SearchUserByCompanyCodeArgs searchUserByCompanyCodeArgs)
        {
            try
            {
                lock (lockWait)
                {
                    _loadingWaitForm = new LoadingWaitForm();
                    _loadingWaitForm.SetCaption(GlobalString.System_Config_String.MbxInfoStr);
                    _loadingWaitForm.SetDescription(GlobalString.System_Config_String.SearchUserStr);
                    _loadingWaitForm.StartPosition = FormStartPosition.CenterScreen;
                }
                var backgroundWorkerSearchUserCompanyCode = new BackgroundWorker();
                backgroundWorkerSearchUserCompanyCode.DoWork += backgroundWorkerSearchUserCompanyCode_DoWork;
                backgroundWorkerSearchUserCompanyCode.RunWorkerAsync(searchUserByCompanyCodeArgs);
                _loadingWaitForm.ShowDialog();
            }
            catch (Exception ex)
            {
                LogLoader.Instance.Log.Error("SearchUserByCompanCode has problem", ex);
                XtraMessageBox.Show("获取用户失败，请联系管理员!", GlobalString.System_Exception_String.MbxErrorStr, MessageBoxButtons.OK,
                                    MessageBoxIcon.Error);
            }
        }

        void backgroundWorkerSearchUserCompanyCode_DoWork(object sender, DoWorkEventArgs e)
        {
            var result = _userService.SearchUserByCompanyCode(e.Argument as SearchUserByCompanyCodeArgs);
            Invoke((EventHandler)delegate
            {
                _loadingWaitForm.Close();
                lv_SearchResult.Items.Clear();
                foreach (var userResult in result.Resultk__BackingField)
                {
                    var listViewItem = new ListViewItem
                    {
                        Text = userResult.UserNamek__BackingField,
                        ImageKey = "people",
                        Tag = userResult
                    };
                    var subListViewItem = new ListViewItem.ListViewSubItem { Text = userResult.CompanyNamek__BackingField };
                    listViewItem.SubItems.Add(subListViewItem);
                    lv_SearchResult.Items.Add(listViewItem);
                }
            });
        }
        #endregion

        #region Public Method
        private IEnumerable<object> ReturnTreeNodeList(TreeNode treeNode)
        {
            var objectCollection = new List<object>();
            if (treeNode.Nodes.Count > 0)
            {
                foreach (TreeNode o in treeNode.Nodes)
                {
                    var tempNodes = ReturnTreeNodeList(o);
                    foreach (object tempNode in tempNodes)
                    {
                        objectCollection.Add(tempNode);
                    }
                }
                //objectCollection.AddRange(from TreeNode node in treeNode.Nodes from TreeNode o in ReturnTreeNodeList(node) select o.Tag);
            }
            else
                objectCollection.Add(treeNode.Tag);
            return objectCollection;
        }
        #endregion
    }
}